using System;
using bitzhuwei.Compiler;

namespace bitzhuwei.AnsiCFormat {
    /// <summary>
    /// Correspond to the Vn node unary_expression in the grammar(AnsiC).
    /// </summary>
    internal partial class Vnunary_expression : IFullFormat {
        // [014] unary_expression = postfix_expression ;
        // [015] unary_expression = '++' unary_expression ;
        // [016] unary_expression = '--' unary_expression ;
        // [017] unary_expression = unary_operator cast_expression ;
        // [018] unary_expression = 'sizeof' unary_expression ;
        // [019] unary_expression = 'sizeof' '(' type_name ')' ;


        private readonly List<IFullFormat> prefix = new();
        private readonly IFullFormat complex;

        private readonly TokenRange _scope;
        public TokenRange Scope => _scope;
        public void FullFormat(BlankConfig? preConfig, TextWriter writer, FormatContext context) {
            var config = new BlankConfig();
            var prefixCount = this.prefix.Count;
            for (var i = 0; i < prefixCount; i++) {
                context.PrintBlanksAnd(this.prefix[i], i == 0 ? preConfig : config, writer);
                if (i + 1 < prefixCount) {
                    context.PrintCommentsBetween(this.prefix[i], this.prefix[i + 1], config, writer);
                }
                else {
                    context.PrintCommentsBetween(this.prefix[i], this.complex, config, writer);
                }
            }
            context.PrintBlanksAnd(this.complex, prefixCount == 0 ? preConfig : config, writer);
        }

        // [015] unary_expression = '++' unary_expression ;
        public void Insert(Token r0) {
            this.prefix.Insert(0, new Prefix0(r0));
            this._scope.start = r0.index;
        }
        class Prefix0 : IFullFormat {
            private readonly TokenRange _scope;
            public TokenRange Scope => _scope;
            public void FullFormat(BlankConfig? preConfig, TextWriter writer, FormatContext context) {
                context.PrintBlanksAnd(r0, preConfig, writer);
            }
            public readonly Token r0;
            public Prefix0(Token r0) {
                this.r0 = r0;
                this._scope = new TokenRange(r0);
            }
        }

        // [016] unary_expression = '--' unary_expression ;
        // Pre/Postfix1 repeated with Pre/Postfix0

        // [018] unary_expression = 'sizeof' unary_expression ;
        // Pre/Postfix2 repeated with Pre/Postfix0


        // [014] unary_expression = postfix_expression ;
        public Vnunary_expression(Vnpostfix_expression r0) {
            this.complex = new complex0(r0);
            this._scope = new TokenRange(r0);
        }
        class complex0 : IFullFormat {
            private readonly TokenRange _scope;
            public TokenRange Scope => _scope;
            public void FullFormat(BlankConfig? preConfig, TextWriter writer, FormatContext context) {
                context.PrintBlanksAnd(r0, preConfig, writer);
            }
            public readonly Vnpostfix_expression r0;
            public complex0(Vnpostfix_expression r0) {
                this.r0 = r0;
                this._scope = new TokenRange(r0);
            }
        }

        // [017] unary_expression = unary_operator cast_expression ;
        public Vnunary_expression(Vnunary_operator r1, Vncast_expression r0) {
            this.complex = new complex1(r1, r0);
            this._scope = new TokenRange(r1, r0);
        }
        class complex1 : IFullFormat {
            private readonly TokenRange _scope;
            public TokenRange Scope => _scope;
            public void FullFormat(BlankConfig? preConfig, TextWriter writer, FormatContext context) {
                var config = new BlankConfig();
                context.PrintBlanksAnd(r1, preConfig, writer);
                context.PrintCommentsBetween(r1, r0, config, writer);
                context.PrintBlanksAnd(r0, config, writer);
            }
            public readonly Vnunary_operator r1;
            public readonly Vncast_expression r0;
            public complex1(Vnunary_operator r1, Vncast_expression r0) {
                this.r1 = r1;
                this.r0 = r0;
                this._scope = new TokenRange(r1, r0);
            }
        }

        // [019] unary_expression = 'sizeof' '(' type_name ')' ;
        public Vnunary_expression(Token r3, Token r2, Vntype_name r1, Token r0) {
            this.complex = new complex2(r3, r2, r1, r0);
            this._scope = new TokenRange(r3, r0);
        }
        class complex2 : IFullFormat {
            private readonly TokenRange _scope;
            public TokenRange Scope => _scope;
            public void FullFormat(BlankConfig? preConfig, TextWriter writer, FormatContext context) {
                var config = new BlankConfig();
                context.PrintBlanksAnd(r3, preConfig, writer);
                context.PrintCommentsBetween(r3, r2, config, writer);
                context.PrintBlanksAnd(r2, config, writer);
                context.PrintCommentsBetween(r2, r1, config, writer);
                context.PrintBlanksAnd(r1, config, writer);
                context.PrintCommentsBetween(r1, r0, config, writer);
                context.PrintBlanksAnd(r0, config, writer);
            }
            public readonly Token r3;
            public readonly Token r2;
            public readonly Vntype_name r1;
            public readonly Token r0;
            public complex2(Token r3, Token r2, Vntype_name r1, Token r0) {
                this.r3 = r3;
                this.r2 = r2;
                this.r1 = r1;
                this.r0 = r0;
                this._scope = new TokenRange(r3, r0);
            }
        }



    }
}
